var chess = {
    list: [],//bg,color,code,icon
    color: 1,//1白棋走，2黑棋走
    color2: 2,//对方的颜色
    icon: [
        "",
        ["", "♙", "♘", "♗", "♖", '♕', '♔'],
        ["", "♟", "♞", '♝', '♜', '♛', '♚'],
    ],
    new(list,color){
        var re=Object.create(chess);
        re.list=fun.copy(list);
        re.color=color;
        re.color2=color==1?2:1;
        return re;
    },
    ai_run(list, color) {
        this.list = list;
        this.color = color;
        this.color2 = color == 1 ? 2 : 1;
        var move = this._my_move_list(color);
        if (move.length > 0) {
            re = move;
        } else {
            //最后的办法
            re = this._ai_run_rand(color);
        }
        return re;
    },
    move(list, from, to) {
        var _list = fun.copy(list);
        var can_run = this.get_can_run(_list, from);
        if (!fun.in_array(to, can_run)) {
            console.log("error:应该能走的，却走不了", list, from, to, can_run);
            return list;
        }
        var item = _list[from];//要移动的棋子
        var v = _list[to];//v.bg没变
        v.color = item.color;
        v.code = item.code;
        v.icon = item.icon;
        if (this._is_queen(v, to)) {
            v.code = 5;
            v.icon = this._get_icon(v.color, v.code);
        }
        _list[to] = v;
        item.color = 0;
        item.code = 0;
        item.icon = "";
        _list[from] = item;
        return _list;
    },
    _get_icon(color, code) {
        if (color > 0 && code > 0) {
            return this.icon[color][code];
        }
        return "";
    },
    check_status(list, color) {
        this.list = list;
        this.color = color;
        this.color2 = color == 1 ? 2 : 1;
        if (!this.has_king(this.list, this.color)) {
            return 'finish';
        }
        if (this.is_checking()) {
            var king = this.get_king_index(this.color);
            if (this.is_dead(king)) {
                return "finish";
            }
            return "checking";
        }
        return "";
    },
    //TODO:目前只考虑了第一步，没考虑过走完这一步后是否会被吃掉，或者是否有其它危险！考虑下一步的话，需要把this.list改成list,不同步的环境下的list是不一样的
    _my_move_list(color) {
        var re = [];
        //是否正在被将军
        re = this.get_checking_move(color);
        if (re.length > 0) {
            console.log("正在被将军", re);
            return re;
        }
        //有哪个棋子需要逃跑？
        re = this.is_need_escape(color);
        if (re.length > 0) {
            console.log("需要逃跑", re);
            return re;
        }
        //可以吃哪些棋子？
        re = this.is_can_eat(color);
        if (re.length > 0) {
            console.log("能吃子", re);
            return re;
        }
        return [];
    },
    _is_queen(v, i) {
        if (v.code != 1) return false;
        if (v.color == 1 && i > 55) {
            return true;
        } else if (v.color == 2 && i < 8) {
            return true;
        }
        return false;
    },
    is_checking() {
        var king = this.get_king_index(this.color);
        var control = this.get_can_run_all(this.color2);
        return fun.in_array(king, control);
    },
    is_dead(king) {
        //能不能逃？
        var king_can_run = this.get_can_run(this.list, king);
        var control=this.get_my_control(this.color2);
        if (king_can_run.length > 0) {
            for(var i in king_can_run){
                var k=king_can_run[i];
                if(k in control == false){
                    var next_list=this.move(this.list,king,k);
                    var next=this.new(next_list);
                    var next_control=next.get_can_run_all(this.color2,true);
                    if(fun.in_array(k,next_control)==false){
                        console.log("将军：我能逃");
                        return false;
                    }
                }
            }
        }
        //能不能挡
        if (this.can_protect_king(king)) {
            console.log("将军：我能挡");
            return false;
        }
        //能不能吃？
        if (this.can_eat()) {
            console.log("将军：我能吃");
            return false;
        }
        return true;
    },
    //可挡:车，象，后
    can_protect_king(king) {
        var color = this.list[king].color;
        var block = this.can_block_td(color);
        var empty_lines = this.get_all_empty_line(king);
        if (empty_lines.length != 1) return false;//如果有多条直线，是不可能用一个子去挡住的
        if (this.block_line(block, empty_lines[0])) {
            return true;
        }
        return false;
    },
    get_all_empty_line(king) {
        var color = this.list[king].color;
        var color2 = color == 1 ? 2 : 1;
        var list = this.get_checking_items(color2);
        if (list.length == 0) return [];
        var re = [];
        for (var i = 0, len = list.length; i < len; i++) {
            var j = list[i];
            var item = this.list[j];
            if (fun.in_array(item.code, [3, 4, 5])) {
                var line = this.get_empty_line(king, j);
                console.log("直线：", king,j,line);
                if (line.length > 0) {
                    re.push(line);
                }
            }
        }
        console.log("需要挡的直线",re);
        return re;
    },
    //挡住一条直线
    block_line(block, line) {
        var len = block.length;
        for (var i = 0; i < len; i++) {
            if (fun.in_array(block[i], line)) {
                return true;
            }
        }
        return false;
    },
    //可以替王挡的位置
    can_block_td(color) {
        var re = [];
        this.list.map((v, i) => {
            if (v.color == color && v.code != 6) {
                var block = this.get_can_run(this.list, i);
                if (block.length > 0) {
                    re = re.concat(block);
                }
            }
        })
        return re;
    },
    // 2 47,4 31
    get_empty_line(a, b) {
        var re = [];
        var min = Math.min(a, b);
        var max = Math.max(a, b);
        var a_row = Math.floor((min + 1) / 8);
        var b_row = Math.floor((max + 1) / 8);
        var a_col = min % 8;
        var b_col = max % 8;
        if (a_row == b_row) {
            var len = b_col - a_col - 1;
            for (var i = 1; i <= len; i++) {
                if (!this.list[min + i].code) {
                    re.push(min + i);
                } else {
                    re = [];
                    break;
                }
            }
        } else if (a_col == b_col) {
            var len = b_row - a_row - 1;
            for (var i = 1; i <= len; i++) {
                if (!this.list[min + 8 * i].code) {
                    re.push(min + 8 * i);
                } else {
                    re = [];
                    break;
                }
            }
        } else if (b_row - a_row == b_col - a_col) {
            var len = b_row - a_row - 1;
            for (var i = 1; i <= len; i++) {
                if (!this.list[min + 9 * i].code) {
                    re.push(min + 9 * i);
                } else {
                    re = [];
                    break;
                }
            }
        } else if (b_row - a_row == a_col - b_col) {
            var len = b_row - a_row - 1;
            for (var i = 1; i <= len; i++) {
                if (!this.list[min + 7 * i].code) {
                    re.push(min + 7 * i);
                } else {
                    re = [];
                    break;
                }
            }
        }
        return re;
    },
    can_eat() {
        var color2 = this.color == 1 ? 2 : 1;
        var checking = this.get_checking_items(color2);//获取正在将军的棋子
        if (checking.lenth > 1) return false;
        var item=checking[0];
        var control=this.get_can_run_all(color2,true);
        if(fun.in_array(item,control)){
            return false;
        }
        console.log("can_eat",item,control);
        var 能吃的 = this.get_can_run_all(this.color);
        if (fun.in_array(item, 能吃的)) {
            return true;
        }
        return false;
    },
    get_checking_items(color) {
        var king_color = color == 1 ? 2 : 1;
        var king = this.get_king_index(king_color);//是否可以通过传参获得？
        var re = [];
        this.list.map((v, i) => {
            if (v.color == color) {
                var can_run = this.get_can_run(this.list, i);
                if (fun.in_array(king, can_run)) {
                    re.push(i);
                }
            }
        })
        return re;
    },
    get_king_index(color) {
        for (var i = 0; i < 64; i++) {
            let item = this.list[i];
            if (item.color == color && item.code == 6) {
                return i;
            }
        }
        return -1;
    },
    is_can_eat(color) {
        var re = this.get_can_run_all(color, "eat");
        if (re.length == 0) return [];
        re.sort((a, b) => {
            return parseInt(b.code) - parseInt(a.code);
        })
        console.log("可能有可以吃的");
        //获取被对方控制的格子
        var control = this.get_can_run_all(this.color2, true);
        for (var i in re) {
            var item = re[i];
            //不会被吃就行了，先这样走
            if (!fun.in_array(item.to, control)) {
                console.log('吃了不会死', item);
                return [item.from, item.to];
            }
            //如果会吃，自己的子一定要较小
            console.log("交换吗？", item)
            if (item.mycode <= item.code) {
                console.log("换子", item.mycode, item.code);
                return [item.from, item.to];
            }
            console.log("不能换");
        }
        return [];
    },
    item_escape(i, control) {
        var can_run = this.get_can_run(this.list, i);
        if (can_run.length == 0) return false;
        var re = [];
        can_run.map(j => {
            if (this.list[i].code <= this.list[j].code) {
                re.push({
                    from: i,
                    to: j,
                    total: this.list[j].code + 6,
                })
            } else if (j in control == false) {
                re.push({
                    from: i,
                    to: j,
                    total: this.list[i].code,
                })
            }
        })
        if (re.length == 0) return false;
        re.sort((a, b) => {
            return parseInt(b.total) - parseInt(a.total);
        })
        return re[0];
    },
    is_need_escape(color) {
        var color2 = color == 1 ? 2 : 1;
        var control = this.get_my_control(color2);
        var my_control = this.get_can_run_all(color, true);
        // console.log("control",color2,control)
        var re = [];
        for (var i = 0; i < 64; i++) {
            var item = this.list[i];
            if (item.color == color && i in control) {
                console.log("要逃", i);
                //没有保护，必须逃走
                if (!fun.in_array(i, my_control)) {
                    console.log("没有保护", i)
                    var run = this.item_escape(i, control);
                    if (run) {
                        re.push(run);
                    }
                } else { //有保护的情况下
                    var arr = control[i];
                    arr.sort((a, b) => {
                        return parseInt(a) - parseInt(b);
                    })
                    var min = arr[0];
                    console.log("有保护", item, this.list[min]);
                    if (item.code > this.list[min].code) {
                        var run = this.item_escape(i, control);
                        if (run) {
                            re.push(run);
                        }
                    }
                }
            }
        }
        if (re.length == 0) return [];
        if (re.length > 1) {
            re.sort((a, b) => {
                return parseInt(b.total) - parseInt(a.total);
            })
        }
        var r = re[0];
        return [r.from, r.to];
    },
    //color参数先保留，但下面很多地方直接使用了this.color
    get_checking_move(color) {
        if (this.is_checking() == false) return [];
        //能吃不？
        var color2 = this.color == 1 ? 2 : 1;
        var checking = this.get_checking_items(color2);//获取正在将军的棋子
        if (checking.lenth > 1) return [];
        var control = this.get_can_run_all(color2, true);
        var to = checking[0];
        if (!fun.in_array(to, control)) {
            for (var i = 0; i < 64; i++) {
                var item = this.list[i];
                if (item.color == this.color) {
                    var arr = this.get_can_run(this.list, i);
                    if (arr.length > 0 && fun.in_array(to, arr)) {
                        console.log("敢将我？我吃")
                        return [i, to];
                    }
                }
            }
        }
        //能逃吗？
        var king = this.get_king_index(this.color);
        var king_can_run = this.get_can_run(this.list, king);
        if (king_can_run.length > 0) {
            for (var i = 0, len = king_can_run.length; i < len; i++) {
                var j = king_can_run[i];
                if (!fun.in_array(j, control)) {
                    var next_list=this.move(this.list,king,j);
                    var next=this.new(next_list);
                    var be_control=next.get_can_run_all(this.color2);
                    if(!fun.in_array(j,be_control)){
                        console.log("被将时，这样逃不会被吃");
                        return [king, j];
                    }else{
                        console.log("被将时，逃了也还会被吃",j);
                    }  
                }
            }
        }
        //TODO:如果有多个子可挡，是否还应该选择用哪个子去挡？要考虑棋子的大小，更复杂一点，还要考虑先后顺序！！！！
        //能挡吗？BUG: 好像又不会挡了！！！
        var line = this.get_all_empty_line(king);
        if (line.length != 1) return [];
        return this.get_block_move(color, line);
    },
    get_block_move(color, line) {
        for (var i = 0; i < 64; i++) {
            if (this.list[i].color == color) {
                var run = this.get_can_run(this.list, i);
                if (run.length > 0) {
                    for (var j = 0, len = run.length; j < len; j++) {
                        if (fun.in_array(run[j], line)) {
                            return [i, run[j]];
                        }
                    }
                }
            }
        }
        return [];
    },
    my_can_run_all(color) {
        var re = {};
        for (var i in this.list) {
            if (this.list[i].color == color) {
                var run = this.get_can_run(this.list, i);
                if (run.length > 0) {
                    re[i] = run;
                }
            }
        }
        return re;
    },
    _ai_run_rand(color) {
        var last = [];
        var control = this.get_can_run_all(this.color2, true);
        var safe = [];
        for (var i in this.list) {
            if (this.list[i].color == color) {
                var run = this.get_can_run(this.list, i);
                if (run.length > 0) {
                    last = [i, run[0]];
                    for (var j in run) {
                        if (!fun.in_array(run[j], control)) {
                            safe.push([i, run[j]]);
                        }
                    }
                }
            }
        }
        if (safe.length > 0) {
            console.log("安全步");
            return fun.array_one(safe);
        }
        console.log("随便步");
        return last;
    },
    has_king(list, color) {
        for (var i = 0; i < 64; i++) {
            if (!list[i]) {
                console.log("error:", list, i);
                return;
            }
            if (list[i].color == color && list[i].code == 6) {
                return true;
            }
        }
        return false;
    },
    get_all_qz(color) {
        var re = [];
        this.list.map((v, i) => {
            if (v.color == color) {
                re.push(i);
            }
        })
        return re;
    },
    get_can_run_all(color, is_control) {
        var control = [];
        for (var i = 0; i < 64; i++) {
            let item = this.list[i];
            if (item.color == color) {
                let tmp = this.get_can_run(this.list, i, is_control);
                if (tmp.length > 0) {
                    if (is_control == "eat") {
                        tmp.map(v => {
                            control.push({
                                from: i,
                                to: v,
                                mycode: item.code,
                                code: this.list[v].code,
                            })
                        })
                    } else {
                        control = control.concat(tmp);
                    }
                }
            }
        }
        return control;
    },
    get_my_control(color) {
        var re = {};
        for (var i in this.list) {
            var item = this.list[i];
            if (item.color == color) {
                var run = this.get_can_run(this.list, i, true);
                if (run.length > 0) {
                    run.map(v => {
                        if (v in re == false) {
                            re[v] = [];
                        }
                        re[v].push(i);
                    })
                }
            }
        }
        return re;
    },
    get_can_run(list, i, is_control) {
        i = parseInt(i);//有些地方会把这个当字符串来处理
        var v = list[i];
        var run = [];
        var row = Math.ceil((i + 1) / 8);
        var col = i % 8 + 1;
        //兵
        if (v.code == 1) {
            if (v.color == 1) {
                if (is_control) {
                    if (col > 1) {
                        run.push(i + 7);
                    }
                    if (col < 8) {
                        run.push(i + 9);
                    }
                } else {
                    if (row == 2) {
                        if (!list[i + 8].code) {
                            run.push(i + 8);
                            if (!list[i + 16].code) {
                                run.push(i + 16);
                            }
                        }
                    }
                    if (col > 1 && list[i + 7].color == 2) {
                        run.push(i + 7);
                    }
                    if (col < 8 && list[i + 9].color == 2) {
                        run.push(i + 9);
                    }
                    if (!list[i + 8].code) {
                        run.push(i + 8);
                    }
                }
            } else {
                if (is_control) {
                    if (col < 8) {
                        run.push(i - 7);
                    }
                    if (col > 1) {
                        run.push(i - 9);
                    }
                } else {
                    if (row == 7) {
                        if (!list[i - 8].code) {
                            run.push(i - 8);
                            if (!list[i - 16].code) {
                                run.push(i - 16);
                            }
                        }
                    }
                    if (col < 8 && list[i - 7].color == 1) {
                        run.push(i - 7);
                    }
                    if (col > 1 && list[i - 9].color == 1) {
                        run.push(i - 9);
                    }
                    if (!list[i - 8].code) {
                        run.push(i - 8);
                    }
                }
            }
            //马
        } else if (v.code == 2) {
            //八个位置
            //左上横
            if (row > 1 && col > 2) {
                run.push(i - 10);
            }
            //左上竖
            if (row > 2 && col > 1) {
                run.push(i - 17);
            }
            //右上横
            if (row > 1 && col < 7) {
                run.push(i - 6);
            }
            //右上竖
            if (row > 2 && col < 8) {
                run.push(i - 15);
            }
            //左下横
            if (row < 8 && col > 2) {
                run.push(i + 6);
            }
            //左下竖
            if (row < 7 && col > 1) {
                run.push(i + 15);
            }
            //右下横
            if (row < 8 && col < 7) {
                run.push(i + 10);
            }
            //右下竖
            if (row < 7 && col < 8) {
                run.push(i + 17);
            }
        }
        //车或后
        if (v.code == 4 || v.code == 5) {
            var left = i % 8;
            for (var j = 1; j <= left; j++) {
                run.push(i - j);
                if (list[i - j].code) break;
            }
            var right = 7 - left;
            for (var j = 1; j <= right; j++) {
                run.push(i + j);
                if (!list[i + j]) {
                    console.log("error:", list, i, j, i + j, list[i + j]);
                }
                if (list[i + j].code) break;
            }
            var top = Math.floor(i / 8);
            for (var j = 1; j <= top; j++) {
                run.push(i - j * 8);
                if (list[i - j * 8].code) break;
            }
            var bottom = 7 - top;
            for (var j = 1; j <= bottom; j++) {
                run.push(i + j * 8);
                if (list[i + j * 8].code) break;
            }
        }
        //象
        if (v.code == 3 || v.code == 5) {
            //左上
            var len = Math.min(row - 1, col - 1);
            for (var j = 1; j <= len; j++) {
                run.push(i - 9 * j);
                if (list[i - 9 * j].code) break;
            }
            //左下
            var len = Math.min(8 - row, col - 1);
            for (var j = 1; j <= len; j++) {
                run.push(i + 7 * j);
                if (list[i + 7 * j].code) break;
            }
            //右上
            var len = Math.min(row - 1, 8 - col);
            for (var j = 1; j <= len; j++) {
                run.push(i - 7 * j);
                if (list[i - 7 * j].code) break;
            }
            //右下
            var len = Math.min(8 - row, 8 - col);
            for (var j = 1; j <= len; j++) {
                run.push(i + 9 * j);
                if (list[i + 9 * j].code) break;
            }
        }
        if (v.code == 6) {
            if (col > 1) {
                run.push(i - 1);
                if (row > 1) {
                    run.push(i - 9);
                }
                if (row < 8) {
                    run.push(i + 7);
                }
            }
            if (col < 8) {
                run.push(i + 1);
                if (row > 1) {
                    run.push(i - 7);
                }
                if (row < 8) {
                    run.push(i + 9);
                }
            }
            if (row > 1) {
                run.push(i - 8);
            }
            if (row < 8) {
                run.push(i + 8);;
            }
        }
        return this.check_run(list,run, v, is_control);
    },
    check_run(list,run, v, is_control) {
        var re = [];
        run.map(i => {
            var item = list[i];
            if (i >= 0 && i <= 63) {
                if (is_control == "eat") { //能吃的
                    if (item.color && item.color != v.color) {
                        re.push(i);
                    }
                } else if (is_control) { //在控制范围内的，包括自己的棋子
                    re.push(i);
                } else if (item.color != v.color) {  //能走的地方，只要不是自己的棋子就可以
                    re.push(i);
                }
            }
        })
        return re;
    },
    init() {
        var bg = 0;
        var line = [4, 2, 3, 6, 5, 3, 2, 4];
        var color = "";
        var code = 0;
        var list = [];
        for (var i = 0; i < 64; i++) {
            if (i % 8 > 0) {
                bg = bg == 1 ? 0 : 1;
            }
            if (i < 16) {
                color = 1;
            } else if (i >= 48) {
                color = 2;
            } else {
                color = 0;
            }
            if (Math.floor(i / 8) == 0) {
                code = line[i];
            } else if (Math.floor(i / 8) == 1 || Math.floor(i / 8) == 6) {
                code = 1;
            } else if (Math.floor(i / 8) == 7) {
                code = line[i % 8];
            } else {
                code = 0;
            }
            list.push({
                bg,
                color,
                code,
                icon: this._get_icon(color, code),
            });
        }
        return list;
    },
}//end